import java.util.ArrayList;

import junit.framework.TestCase;

//Matt Lee: I made a test case for the JUnit test cases.  Feel free to add whatever you wish to 
//test this.

/*
 * HOW TO WRITE A JUNIT TEST CASE:
 * 
 * public void testExample()
 * {
 * }
 * 
 */
public class DoctorsOfficeTestCases extends TestCase {

	public void testExample(){  //ALL JUNIT TESTS MUST BE VOID AND START WITH TEST IN TEXT.
		System.out.println("DAMN YOU CODE AUDIT!");
		//Treat it like it's a main method.  Instantiate the appropriate objects,  execute methods,  etc...
		//The main way that JUnit tests will work is like this:
		
		//In general,  a test case will test the methods and instantiations you write within the void method.
		//If any of these fail,  it will let you know.  
		
		//THE ASSERTIONS:
		//An assertion is testing to make sure that the desired result is equivalent to what you got.
		//This is best to test for return methods.
		
/*		assertEquals(1, 1);  //This tests to see if 1 equals 1
		assertEquals("My name is Matt.",  "My name is Zipp.");  //This tests if the two are the same.
		assertEquals("my hopeful result",  this.runMethodForAResult);  //This compares the hopeful result with the one you actually get.
		
		The only other assertion is assertsFalse,  
		which acts the same way as assertEquals 
		except it checks for false.
	*/
		
		//THE ERRORS:
		//A red error means that the program crashed.  
		//A blue error means the program did not get the proper result.  
		
		//If either of the above are true,  then it will not test the other assertions below,  much like a traditional method would.
		
		//ALSO,  very important:
		//It'll tell you where the crash is occuring OR what the actual result you got was.
		//So,  you have a good ballpark guess of locating the error.
		
	}
	
	public void testLogIn(){
		
	}
	
	public void testPatient(){
		//Creates a default patient
		Patient patient = new Patient();
		
		//Create a basic patient
		Patient patient1 = new Patient("Matt",  "matt",  "dummy",  
				"4323",  "703",  "",  "",  "",  "");
		
		Appointment ap1 = new Appointment(3,  3,  "NoReason",  
				new Doctor(),  "patient",  false);
		
		//Make an appointment.
		patient1.makeAppointment(ap1);
		
		assertEquals(1,  patient1.hasAppointment());
		
		patient1.makeAppointment(ap1);
		assertEquals(2,  patient1.hasAppointment());
		
		Patient patientDuplicate = patient1.viewUser();
		assertEquals(patient1,  patientDuplicate);
		
		ArrayList appointments = patient1.viewAppointments();
		
		assertEquals(2,  appointments.size());
		appointments.remove(0);
		assertEquals(1,  appointments.size());
		assertEquals(1,  patient1.hasAppointment());
		appointments.remove(0);
		assertEquals(0,  patient1.hasAppointment());
		
	}
	
	public void testDoctor(){
		/*
		 * int date,  int time,  Doctor doctor, 
			ArrayList<String> symptoms,  Nurse nurse,  double bloodPressure, 
			double pulse,  double temperature,  double height,  double weight, 
			ArrayList<String> diagnosis,  Patient patient
		 */
		Doctor doc = new Doctor();
		Appointment ap1 = new Appointment(3,  3,  
				"NoReason",  new Doctor(),  "patient",  false);
		doc.addAppointment(ap1);
		DoctorOrders docO = new DoctorOrders("String doc");
		doc.addDocOrders(new TreatmentRecord( new Patient(),  "3", 
				"3:00",  doc,  "Something",  new Nurse(),  10.0,  10.0,  90.0,  35,  22,  
				"Something else"),  docO);
	}

	public void testInitialization(){  //Initializes some of the classes.
		//Creates a default patient
		Patient patient = new Patient();
		
		//Create a basic patient
		Patient patient1 = new Patient("Matt",  "matt", "dummy", 
				"4323", "703", "", "", "", "");
		
		//Creates a nurse
		Nurse nurse = new Nurse();
		
		//Creates a user that's cast as a doctor.
		Doctor doctor1=new Doctor("Matt",  "matt",  "dummy", 
				"4323",  "703",  "email",  "age");
	
		//Creates a system admin.
		SystemAdmin admin = new SystemAdmin();
	
		//Create a treatment record.
		TreatmentRecord record = new TreatmentRecord(patient1, "10",  
				"10:00",  doctor1,  "Something", 
				nurse,  1.0,  1.0,  1.0,  1.0,  1.0,  "Something else");
		
		//Create a medical record.
		MedicalRecord patientRecord = new MedicalRecord(patient1);
		

	}

	//This will be tested by Dolan.
	public void testAppointments(){
		//Create a basic patient
		Patient patient1 = new Patient("William",  "Dolan", 
				"DrWho", "1007", "964", "", "", "", "");
		Doctor Who = new Doctor("The Doctor",  "TheDoctor", 
				"TennantRules",  "TARDIS",  
				"(800)9642738",  "thedoctor@tardis.com",  "913");
		Appointment ap1 = new Appointment(3,  3,  "Headache", 
				new Doctor(),  "patient",  false);
		Appointment ap2 = new Appointment(5, 5,  "Bubonic Plague", 
				Who, "patient", false);
		
		//Making and removing an appointment from the patient point of view.
		patient1.makeAppointment(ap1);
		assertEquals(1,  patient1.hasAppointment());
		patient1.makeAppointment(ap1);
		assertEquals(2,  patient1.hasAppointment());
		
		ArrayList apps = patient1.viewAppointments();
		
		assertEquals(2,  apps.size());
		apps.remove(0);
		assertEquals(1,  apps.size());
		assertEquals(1,  patient1.hasAppointment());
		apps.remove(0);
		assertEquals(0,  patient1.hasAppointment());
		
		// Checking for duplicates. Set it to False and the Test will crash.
		patient1.makeAppointment(ap1);
		assertEquals(1,  patient1.hasAppointment());
		patient1.makeAppointment(ap1);
		assertEquals(2,  patient1.hasAppointment());
		assertEquals(true, apps.get(0).equals(apps.get(1)));
		
		//Checking that the two appointments are different.
		patient1.makeAppointment(ap2);
		assertEquals(3,  patient1.hasAppointment());
		assertEquals(false, ap1.equals(ap2));
		assertEquals(false, apps.get(0).equals(apps.get(2)));
		
		
	}

	//This will be test by John.
	public void testDelete(){
		System.out.println("John Test:");
		Patient Bob = new Patient("Bob, ",  "b1",  
				"secret",  "New York",  "8675309",  
				"bobcat@mail.com",  "75",  "Medicare",  "peanut butter");
		SystemAdmin Bobo = new SystemAdmin("Bobo, ", "b2", 
				"secreter",  "Canada",   "123123123", 
				"bobdog@mail.com",  "75");
		Nurse Bobobo = new Nurse("Bobobo",  "b3",  
				"secretest",  "China",  "911",  
				"bobcatdog@mail.com",  "75");
		Doctor Bobobobo = new Doctor("Bobobobo",  "b4",  
				"secretester", "Florida",  
				"123",  "bobcatdogfish@mail.com",  "75");
		
		UserDatabase.addUser(Bob,  UserDatabase.PATIENT);
		UserDatabase.addUser(Bobo,  UserDatabase.SYSTEM_ADMIN);
		UserDatabase.addUser(Bobobo,  UserDatabase.NURSE);
		UserDatabase.addUser(Bobobobo,  UserDatabase.DOCTOR);
		
		ArrayList<Patient> patients = 
			UserDatabase.searchPatient(Bob.getUsername(),  UserDatabase.USERNAME_SEARCH);
		ArrayList<SystemAdmin> admins = 
			UserDatabase.searchAdmin(Bobo.getUsername(),  UserDatabase.USERNAME_SEARCH);
		ArrayList<Nurse> nurses = 
			UserDatabase.searchNurse(Bobobo.getUsername(),  UserDatabase.USERNAME_SEARCH);
		ArrayList<Doctor> doctors = 
			UserDatabase.searchDoctor(Bobobobo.getUsername(), 
					UserDatabase.USERNAME_SEARCH);
		
		assertTrue(UserDatabase.patientList.contains(Bob));
		assertTrue(UserDatabase.doctorList.contains(Bobobobo));
		assertTrue(UserDatabase.nurseList.contains(Bobobo));
		assertTrue(UserDatabase.adminList.contains(Bobo));
		assertFalse(UserDatabase.patientList.contains(Bobo));
		assertFalse(UserDatabase.patientList.isEmpty());

		UserDatabase.removeUser(Bob.getUsername(),  UserDatabase.PATIENT);
		UserDatabase.removeUser(Bobo.getUsername(),  UserDatabase.SYSTEM_ADMIN);
		UserDatabase.removeUser(Bobobo.getUsername(),  UserDatabase.NURSE);
		UserDatabase.removeUser(Bobobobo.getUsername(),  UserDatabase.DOCTOR);
		
		assertFalse(UserDatabase.patientList.contains(Bob));
		assertTrue(UserDatabase.adminList.contains(Bobo)); // Always need one! No matter What!
		assertFalse(UserDatabase.nurseList.contains(Bobobo));
		assertFalse(UserDatabase.doctorList.contains(Bobobobo));

	}

	//Now,  let's have the users directly remove people.
	public void testDeleteVer2(){
		
		Patient Bob = new Patient("Bob, ",  "b1",  
				"secret",  "New York",  "8675309",  
				"bobcat@mail.com",  "75",  
				"Medicare",  "peanut butter");
		SystemAdmin Bobo = new SystemAdmin("Bobo, ", "b2", 
				"secreter",  "Canada",   "123123123", 
				"bobdog@mail.com",  "75");
		Nurse Bobobo = new Nurse("Bobobo",  "b3",  
				"secretest",  "China",  "911",  
				"bobcatdog@mail.com",  "75");
		Doctor Bobobobo = new Doctor("Bobobobo",  "b4", 
				"secretester", "Florida",  "123",  
				"bobcatdogfish@mail.com",  "75");
		
		UserDatabase.addUser(Bob,  UserDatabase.PATIENT);
		UserDatabase.addUser(Bobo,  UserDatabase.SYSTEM_ADMIN);
		UserDatabase.addUser(Bobobo,  UserDatabase.NURSE);
		UserDatabase.addUser(Bobobobo,  UserDatabase.DOCTOR);
		
		//System Admin,  remove from the system.
		
		Bobo.deleteUser(Bob.getUsername(),  UserDatabase.PATIENT);
		assertFalse(UserDatabase.patientList.contains(Bob));
		UserDatabase.addUser(Bob,  UserDatabase.PATIENT);
		
		//Doctor,  remove patient from the system.
		Bobobobo.deletePatient(Bob.getUsername());
		assertFalse(UserDatabase.patientList.contains(Bob));
		UserDatabase.addUser(Bob,  UserDatabase.PATIENT);
		
		//Nurse,  remove Bob from the system.
		Bobobo.deletePatient(Bob.getUsername());
		assertFalse(UserDatabase.patientList.contains(Bob));
		
	}
	
	//This will be tested by Matt.
	public void testUserDatabasePatientSearch(){
		Patient matt = new Patient("Matt",  "mlee",  
				"mypassword",  "myaddress",  "7034242222",  
				"random@gmail.com",  "21",  "insurance",  "allergies");
		Patient mike = new Patient("Mike",  "mzipp",  
				"newpass",  "address",  "12345678", 
				"rand@gmail.com",  "21",  "insur",  "ahchoo");
		Patient matt2 = new Patient("MattA",  "mlee",  
				"mypass",  "myaddress",  "7034242222", 
				"random@gmail.com",  "21",  "insurance",  "allergies");
		Patient pat = new Patient();
		Doctor doc = new Doctor("Doctor",  "doc",  
				"docpass",  "docaddress",  "123456",  
				"rand@gmaillcom",  "31");
		Nurse nur = new Nurse("Nurse",  "nur",  
				"nurpass",  "nuraddress",  
				"12345",  "rand@gmail.com",  "25");
		
		//User use = new User()
		
		UserDatabase.addUser(matt,  UserDatabase.PATIENT);
		UserDatabase.addUser(mike,  UserDatabase.PATIENT);
	//	UserDatabase.addUser(matt2,  UserDatabase.PATIENT);
		UserDatabase.addUser(doc,  UserDatabase.DOCTOR);
		UserDatabase.addUser(nur,  UserDatabase.NURSE);
		//UserDatabase.addUser(pat,  UserDatabase.PATIENT);
		
		//Test to see that the correct patient is found by patient's username.
		ArrayList<Patient> patients = 
			UserDatabase.searchPatient(
					matt.getUsername(),  UserDatabase.USERNAME_SEARCH);
		assertEquals(matt,  patients.get(0));

		//Test to see that correct patient is found by a simple string username.
		patients = 
			UserDatabase.searchPatient(
					"mlee",  UserDatabase.USERNAME_SEARCH);
		assertEquals(matt,  patients.get(0));
		
		//Test to see that the correct patient is found by name.
		patients = 
			UserDatabase.searchPatient(
					matt.getName(),  UserDatabase.NAME_SEARCH);
		assertEquals(matt.getName(),  patients.get(0).getName());
		
		//Test to see that the correct patient is found by name.  This test SHOULD fail.
		patients = UserDatabase.searchPatient(matt.getName(),  UserDatabase.NAME_SEARCH);
		assertNotSame(matt.getName(), patients.get(0));
		
		//Test to see that a patient is found by a string name.
		patients = UserDatabase.searchPatient("Matt",  UserDatabase.NAME_SEARCH);
		assertEquals(matt.getName(),  patients.get(0).getName());
		
		//Test to see that a patient that has no name is not found.
		patients = UserDatabase.searchPatient(null,  UserDatabase.USERNAME_SEARCH);
		assertTrue(patients.isEmpty());
		//Test to see that a patient that has not been added is not found by a string username.
		patients = UserDatabase.searchPatient("mlee2",  UserDatabase.USERNAME_SEARCH);
		assertTrue(patients.isEmpty());
		
		//Test to see that a patient that has not been added to the database is not found when searched by name.
		patients = UserDatabase.searchPatient("Philip",  UserDatabase.NAME_SEARCH);
		assertTrue(patients.isEmpty());
		//Test to see that the doctor is not found in the patients list.
		patients = 
			UserDatabase.searchPatient(
					doc.getUsername(),  UserDatabase.USERNAME_SEARCH);
		assertTrue(patients.isEmpty());
		
		//Test to see that patients with the same username are added to the list.  THIS TEST FAILS.
		patients = UserDatabase.searchPatient("mlee",  UserDatabase.USERNAME_SEARCH);
		assertNotSame(2,  patients.size());
	

	
	
	}
	
	public void testUserUpdate(){
		Patient matt = new Patient("Matt",  "mlee", 
				"mypassword",  "myaddress",  "7034242222", 
				"random@gmail.com",  "21",  "insurance",  "allergies");
		Patient mike = new Patient("Mike",  "mzipp",  
				"newpass",  "address",  "12345678", 
				"rand@gmail.com",  "21",  "insur",  "ahchoo");
		Patient matt2 = new Patient("MattA",  "mlee",  
				"mypass",  "myaddress",  "7034242222",  
				"random@gmail.com",  "21",  "insurance",  "allergies");
		Patient pat = new Patient();
		Doctor doc = new Doctor("Doctor",  "doc",  
				"docpass",  "docaddress",  "123456",  
				"rand@gmaillcom",  "31");
		Nurse nur = new Nurse("Nurse",  "nur",  
				"nurpass",  "nuraddress",  "12345", 
				"rand@gmail.com",  "25");
		SystemAdmin Bobo = new SystemAdmin("Bobo, ", "b2", 
				"secreter",  "Canada",   "123123123",  
				"bobdog@mail.com",  "75");

		//IN GENERAL,  APPLIES FOR ALL EXTENSIONS FOR USER.
		matt.setAddress("Somewhere on Georgia Tech Campus");
		matt.setAllergies("pollen");
		matt.setInsuranceCarrier("Insurer");
		matt.setPassword("birds");
		
		assertEquals("Somewhere on Georgia Tech Campus",  matt.getAddress());
		assertEquals("pollen",  matt.getAllergies());
		assertEquals("Insurer",  matt.getInsuranceCarrier());
		assertEquals("birds",  matt.getPassword());
		
		assertEquals(null,  pat.getName());
		pat.setName("Patrick");
		assertEquals("Patrick", pat.getName());
		
		doc.setEmail("newemail@gatech.edu");
		nur.setEmail("nurseemail@gatech.edu");
		//Bobo.createUser(new User(),  UserDatabase.PATIENT);
		
	}

	public void testInvoice(){
		
		Prescription paras = new Prescription("DeathClock",  66.00);
		Prescription pars = new Prescription("Adrenaline",  25.00);
		Labwork labrador = new Labwork("Euthanasia",  354.11);
		Labwork lark = new Labwork("Larkston",  244.11);
		
		ArrayList<Prescription> prescriptions = new ArrayList<Prescription>();
		ArrayList<Labwork> labwork = new ArrayList<Labwork>();
		prescriptions.add(paras);
		prescriptions.add(pars);
		labwork.add(labrador);
		labwork.add(lark);
		
		Doctor doc = new Doctor("Doctor",  "doc",  
				"docpass",  "docaddress",  "123456", 
				"rand@gmaillcom",  "31");
		DoctorOrders newDocs = new DoctorOrders(doc.getName(),  prescriptions,  labwork);
		
		//Create a basic patient
		Patient patient1 = new Patient("Matt",  "matt", 
				"dummy", "4323", "703", 
				"", "", "", "");

		Nurse nurse = new Nurse();
		
		//Creates a user that's cast as a doctor.
		Doctor doctor1=new Doctor("Matt",  "matt", 
				"dummy",  "4323",  "703",  
				"email",  "age");
	
		TreatmentRecord record = new TreatmentRecord(patient1, "10",  "10:00", 
				doctor1,  "Something",  nurse,  
				1.0,  1.0,  1.0,  1.0,  1.0,  
				"ThePatient");
		record.setDocOrders(newDocs);
		PatientInvoice invoice = new PatientInvoice(record);
		assertEquals(689.22,  invoice.getPatientBill());

		
		
	}

	//Test the DoctorsOrders
	public void testCRUD_DocOrders(){
		Prescription paras = new Prescription("DeathClock",  66.00);
		Prescription pars = new Prescription("Adrenaline",  25.00);
		Labwork labrador = new Labwork("Euthanasia",  354.11);
		Labwork lark = new Labwork("Larkston",  244.11);
		Doctor doctor1 = new Doctor();
		Nurse nurse = new Nurse();
		Patient patient1 = new Patient();
		ArrayList<Prescription> prescriptions = new ArrayList<Prescription>();
		ArrayList<Labwork> labwork = new ArrayList<Labwork>();
		prescriptions.add(paras);
		prescriptions.add(pars);
		labwork.add(labrador);
		labwork.add(lark);
		
		//Create
		Doctor doc = new Doctor("Doctor",  "doc", 
				"docpass",  "docaddress",  "123456", 
				"rand@gmaillcom",  "31");
		DoctorOrders newDocs = new DoctorOrders(doc.getName(),  prescriptions,  labwork);
		newDocs.setDoctorName("The new doctor.");
		newDocs.setAdditionalInstructions("See me");
		TreatmentRecord record = 
			new TreatmentRecord(patient1, "10",  
					"10:00",  doctor1,  "Something",  
				nurse,  1.0,  1.0,  1.0,  1.0,  1.0,  "Something");
		doctor1.addDocOrders(record,  newDocs);
		//Update
		assertEquals("The new doctor.",  newDocs.getDoctorName());
		assertEquals("See me", newDocs.getAdditionalInstructions());
		
		//Delete
		doctor1.removeDocOrders(record);
		assertEquals(null,  record.getDocOrders());
		
		
	}

	//Test Case done by Zipp
	public void testLoadSave(){
		//Clear anything in database
		UserDatabase.removeAll();
		UserDatabase.adminList.clear();
		
		User doctor = new Doctor("The Doctor",  "dwho", 
				"tardis",  null,  null,  null,  null);
		User dalek = new SystemAdmin("The Dalek",  "dalek", 
				"destroy",  null,  null,  
				null,  null);
		User amy = new Patient("The Companion",  "amy",  
				"companion",  null,  null,  
				null,  null,  null,  null );
		User rory = new Patient("The Other Companion",  
				"rory",  "companion",  null,  null,  
				null,  null,  null,  null );
		User nurse = new Nurse("The Joyful Nurse",  
				"nurseJoy",  "pkmn",  
				null,  null,  null,  null);
		
		//Add all the users to the database
		UserDatabase.addUser(nurse,  UserDatabase.NURSE);
		UserDatabase.addUser(rory,  UserDatabase.PATIENT);
		UserDatabase.addUser(amy,  UserDatabase.PATIENT);
		UserDatabase.addUser(doctor,  UserDatabase.DOCTOR);
		UserDatabase.addUser(dalek,  UserDatabase.SYSTEM_ADMIN);
		
		//Get pre-save/load results to test against post-save/load results
		ArrayList<User> preResults = UserDatabase.searchUser("The",  
				UserDatabase.NAME_SEARCH);
		assertEquals(preResults.size(),  5);
		
		DataSaveLoad.save();
		
		UserDatabase.removeUser("nurseJoy",  UserDatabase.NURSE);
		UserDatabase.removeUser("rory",  UserDatabase.PATIENT);
		UserDatabase.removeUser("amy",  UserDatabase.PATIENT);
		UserDatabase.removeUser("dwho",  UserDatabase.DOCTOR);
		UserDatabase.removeUser("dalek",  UserDatabase.SYSTEM_ADMIN);
		
		//Make sure everything is removed except last system admin,  then remove that manually
		ArrayList<User> midResults = 
			UserDatabase.searchUser("",  UserDatabase.NAME_SEARCH);
		assertEquals(midResults.size(),  1);
		UserDatabase.adminList.clear();
		
		//Everything gone now
		midResults = UserDatabase.searchUser("",  UserDatabase.NAME_SEARCH);
		assertEquals(midResults.size(),  0);
		
		DataSaveLoad.load();
		
		//Get the post-save/load results and compare to pre-save/load
		ArrayList<User> postResults =
			UserDatabase.searchUser("The",  UserDatabase.NAME_SEARCH);
		assertEquals(postResults.size(),  5);
		
		//Check for all the same usernames
		for(int i = 0; i < 5; i++){
			assertEquals(postResults.get(0).username,  preResults.get(0).username);
		}
	}
	
	public void testOfficeProcedures(){
		ProcedureDatabase.addPrescription(new Prescription("Alcohol", 25.00));
		ArrayList<Prescription> prescrips = 
			(ArrayList) ProcedureDatabase.PrescriptionList;
		assertEquals(prescrips.get(0).getName(), "Alcohol");
		ProcedureDatabase.removePrescription("Alcohol");
		assertEquals(prescrips.size(), 0);
		
	}
	
}
